package com.founder.android.parser;

import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

import android.os.Handler;
import android.sax.Element;
import android.sax.ElementListener;
import android.sax.EndElementListener;
import android.sax.RootElement;
import android.util.Log;
import android.util.Xml;
import android.util.Xml.Encoding;

/**
 * xml解析器
 * @author chen_weihua
 *
 */
public class BaseXmlParser extends BaseParser {
	
	private String xml;
	
	private InputStream in;
	
	private Reader reader;
	
	private Encoding encoding;
	
	private XmlParserHandler handler;
	
	public BaseXmlParser(Handler osHandler, 
			ParserListener callback, XmlParserHandler handler) {
		super(osHandler, callback);
		this.handler = handler;
		encoding = Xml.Encoding.UTF_8;
	}
	
	/**
	 * 异步解析
	 */
	public void run() {
		final Copyable data = handler.getPraseData();
		final RootElement root = handler.getRootElement();
		root.setElementListener(new ElementListener() {
			
			@Override
			public void end() {
				onParserDocumentEnd();
			}
			
			@Override
			public void start(Attributes attributes) {
				onParserDocumentStart();
			}
		});
		
		Element item = handler.getItem(root);
		item.setEndElementListener(new EndElementListener() {
			@Override
			public void end() {
				onParserItem(data.clone());
				data.clean();
			}
		});
		
		handler.config(item, data);
		
		try {
			try {
				if (in != null) {
					Xml.parse(in, encoding, root.getContentHandler());
				} else if (reader != null) {
					Xml.parse(reader, root.getContentHandler());
				} else if (xml != null) {
					Xml.parse(xml, root.getContentHandler());
				}  else {
					Log.w("BaseXmlParser", "no InputStream or XML to parse!");
				}
			} finally {
				if (in != null) {
					in.close();
				}
				if (reader != null) {
					reader.close();
				}
			}
		} catch (SAXException e) {
			onParserError(e);
		} catch (IOException e) {
			onParserError(e);
		}
	}

	public void setXml(String xml) {
		this.xml = xml;
	}

	public void setInputStream(InputStream in) {
		this.in = in;
	}

	public void setReader(Reader reader) {
		this.reader = reader;
	}

	public void setEncoding(Encoding encoding) {
		this.encoding = encoding;
	}

}
